package com.xbongbong.paas.help;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.formula.service.FunctionService;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.ComboTypeEnum;
import com.xbongbong.paas.enums.DateTimeEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.FilterConditionsPoJo;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.help.factory.OperatorFieldHandler;
import com.xbongbong.paas.help.factory.OperatorFieldHandlerFactory;
import com.xbongbong.paas.pojo.OperationsPojo;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.MathUtil;
import com.xbongbong.paas.toolbox.util.PaasStringUtil;
import com.xbongbong.paas.toolbox.util.RegexUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.parent.condition.ConditionFieldHandler;
import com.xbongbong.parent.condition.ConditionFieldHandlerFactory;
import com.xbongbong.parent.util.ConditionUtil;
import com.xbongbong.pro.businessrule.pojo.BusinessRuleExplainPojo;
import com.xbongbong.pro.businessrule.pojo.BusinessRuleInfoPojo;
import com.xbongbong.pro.businessrule.pojo.EqualsResultPojo;
import com.xbongbong.pro.businessrule.pojo.dto.OperationDTO;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.enums.businessrule.enums.RuleValueTypeEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessRuleErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ProErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.form.pojo.RuleTargetPojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.enums.UserTeamEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 业务规则中复杂格式的相关解析
 * 例如：下拉框/单选按钮/关联数据/下拉复选/复选框
 * @author 吴峰
 * @version 1.0
 * @date 2020-02-13 11:09
 * @since 1.0
 **/
@Component
public class ComplexFormatHelp {

    private static final Logger LOGGER = LoggerFactory.getLogger(ComplexFormatHelp.class);

    @Resource
    private ProFormHelp proFormHelp;
    @Resource
    private FunctionService functionService;
    @Resource
    private ConditionFieldHandlerFactory conditionFieldHandlerFactory;
    @Resource
    private OperatorFieldHandlerFactory operatorFieldHandlerFactory;
    @Resource
    private FormDataFormExplainHelper formDataFormExplainHelper;

    /**
     * 根据字段，获取对应的值
     * @param operationDTO
     * @param operationsPojo
     * @param targetFormDataEntity 目标表单数据实体
     * @param subData 暂时无用
     * @param businessRuleExplainPojo 子表单字段解释封装
     * @param businessRuleInfoPojo 实体
     * @param thisSubFormData 当前表单符合条件的子表单数据
     * @param targetSubFormData 目标表单的子表单数据
     * @return com.xbongbong.pro.businessrule.pojo.EqualsResultPojo
     * @author 吴峰
     * @date 2020/10/10 10:12
     * @throws XbbException
     */
    public EqualsResultPojo newComplexFormat(OperationDTO operationDTO, OperationsPojo operationsPojo, PaasFormDataEntityExt targetFormDataEntity, JSONObject subData,
                                             BusinessRuleExplainPojo businessRuleExplainPojo, BusinessRuleInfoPojo businessRuleInfoPojo, JSONObject thisSubFormData,
                                             JSONObject targetSubFormData) throws XbbException {

        EqualsResultPojo equalsResult = new EqualsResultPojo();

        String corpid = operationDTO.getCorpid();
        Map <String, FieldAttrEntity> thisExplainMap = operationDTO.getThisExplain();
        Map <String, FieldAttrEntity> targetExplainMap = operationDTO.getTargetExplain();
        PaasFormDataEntity thisDataEntity = operationDTO.getPaasFormDataEntity();
        JSONObject thisData = thisDataEntity.getData();
        JSONObject targetData = targetFormDataEntity.getData();
        Long thisFormId = thisDataEntity.getFormId();
        Long targetFormId = operationDTO.getTarget().getFormId();
        Integer targetBusinessType = operationDTO.getTarget().getLinkBusinessType();
        String formula = operationsPojo.getFormulaInfo().getFormula();
        Integer businessType = operationDTO.getBusinessType();
        String[] formulaArray = RegexUtil.getFormulaAttr(formula);
        List<FilterConditionsPoJo> filterConditionList = operationDTO.getFilterConditionList();

        Map<String, FieldAttrEntity> thisSubExplainMap = businessRuleExplainPojo.getThisSubExplainMap();
        Map<String, FieldAttrEntity> targetSubExplainMap = businessRuleExplainPojo.getTargetSubExplainMap();

        // 条件为：目标表单子表单内字段等于当前表单子表单内字段
        boolean isSubFormAndSubForm = businessRuleExplainPojo.getIsSubFormAndSubForm();
        // 条件为：目标表单子表单内字段等于当前表单主字段
        boolean isSubFormAndMain = businessRuleExplainPojo.getIsSubFormAndMain();

        boolean isMainAndSubForm = businessRuleExplainPojo.getIsMainAndSubForm();

        for (int i = 0; i < formulaArray.length; i++) {
            String formulaAttr = formulaArray[i];
            Object value = null;
            String attr = "";
            if (formulaAttr.contains("self.")) {
                // 本表单的字段操作
                attr = formulaAttr.replaceAll("self.", "").replaceAll("[\\{\\}]", "");
                if (attr.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                    if (isSubFormAndSubForm || isMainAndSubForm) {
                        // 子赋值子
                        // 动态值
                        List<String> thisAttrList = ExplainUtil.getAttrByPoint(attr);
                        String thisSubKey = "";
                        if (thisAttrList.size() == 2) {
                            thisSubKey = thisAttrList.get(1);
                        }
                        value = getData(thisSubKey, thisSubExplainMap, thisDataEntity, thisSubFormData, thisFormId, businessType, corpid, businessRuleInfoPojo);
                    }
                } else {
                    value = getData(attr, thisExplainMap, thisDataEntity, thisData, thisFormId, businessType, corpid, businessRuleInfoPojo);
                }
            } else if (RegexUtil.isStartWithNumber(formulaAttr) || formulaAttr.contains("workOrder_")) {
                // 目标表单
                Integer startNum = formulaAttr.indexOf(".")+1;
                Integer length = formulaAttr.length();
                attr = formulaAttr.substring(startNum, length).replaceAll("[\\{\\}]", "");
                if (attr.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                    List<String> attrList = ExplainUtil.getAttrByPoint(attr);
                    attr = attrList.get(1);
                    if (isSubFormAndSubForm) {
                        // 子赋值子
                        value = getData(attr, targetSubExplainMap, targetFormDataEntity, targetSubFormData, targetFormId, targetBusinessType, corpid, businessRuleInfoPojo);

                    } else if (isSubFormAndMain) {
                        // 主赋值子
                        value = getData(attr, targetSubExplainMap, targetFormDataEntity, targetSubFormData, targetFormId, targetBusinessType, corpid, businessRuleInfoPojo);

                    }
                } else {
                    value = getData(attr, targetExplainMap, targetFormDataEntity, targetData, targetFormId, targetBusinessType, corpid, businessRuleInfoPojo);
                }

            } else if (formulaAttr.contains("user.")) {
                value = formulaAttr.replace("user.", "").replaceAll("[\\{\\}]", "");
                value = "\""+ value + "\"";
            }else if (formulaAttr.contains("dept.")) {
                value = formulaAttr.replace("dept.", "").replaceAll("[\\{\\}]", "");
            }
            if (Objects.isNull(value)) {
                equalsResult.setUpdate(true);
                return equalsResult;
            } else {
                formula = formula.replace(formulaAttr, value.toString());
            }
        }
        equalsResult.setUpdate(true);
        equalsResult.setFormula(formula);
        return equalsResult;
    }

    /**
     * 给公式用的获取数据。可能拿的是本表单的也可能拿的是目标表单的
     * @param targetAttr 目标表单字段
     * @param explainMap 字段容器
     * @param formDataEntity 目标表单数据或者本表单数据
     * @param data 可能会是子表单的数据集合
     * @param formId 表单id
     * @param businessType 表单的业务类型
     * @param corpid 公司id
     * @return
     * @throws XbbException
     */
    private Object getData(String targetAttr, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntity formDataEntity, JSONObject data,
                           Long formId, Integer businessType, String corpid, BusinessRuleInfoPojo businessRuleInfoPojo) throws XbbException {
        Object value = null;
        if (!targetAttr.contains(".")) {

            FieldAttrEntity fieldAttrEntity = explainMap.get(targetAttr);
            value = getDataByFieldType(fieldAttrEntity, explainMap, formDataEntity, data, formId, businessType, corpid, businessRuleInfoPojo);
        }
        return value;
    }

    /**
     * 根据条件判断是否相等（子表单字段等于子表单字段）
     * @param formDataEntityExt 目标表单的外部数据
     * @param subData 目标表单的子表单数据
     * @param operationDTO 实体
     * @param operationsPojo 操作方式
     * @return
     */
    public EqualsResultPojo equalsByCondition(PaasFormDataEntityExt formDataEntityExt, JSONObject subData, OperationDTO operationDTO,
                                              OperationsPojo operationsPojo) throws XbbException{
        boolean update = false;
        List<FilterConditionsPoJo> conditionList = operationDTO.getFilterConditionList();
        Map<String, FieldAttrEntity> thisExplainMap = operationDTO.getThisExplain();
        Map<String, FieldAttrEntity> targetExplainMap = operationDTO.getTargetExplain();
        String corpid = operationDTO.getCorpid();
        PaasFormDataEntity thisDataEntity = operationDTO.getPaasFormDataEntity();
        JSONObject thisData = thisDataEntity.getData();
        JSONObject subFormData = thisDataEntity.getSubFormData() == null ? new JSONObject() : thisDataEntity.getSubFormData();
//        Map<String, FilterConditionsPoJo> targetAttrSet = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        String subFormKey = "";
        Map<String, Map<String, FieldAttrEntity>> subExplainMap = new HashMap<>(conditionList.size());
        Map<String, FieldAttrEntity> targetSubExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String, FieldAttrEntity> thisSubExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // 先将子表单的字段拿出来，因为子表单仅限于同一子表单，所以存下下来
        List<FilterConditionsPoJo> copyConditionList = new ArrayList<>();
        for (FilterConditionsPoJo item : conditionList) {
            // 动态值，目标表单字段为主字段，当前表单字段为子表单字段
            if (Objects.equals(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), item.getValueType()) && item.getValueAttr().contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                String thisAttr = item.getValueAttr();
                List<String> thisAttrList = ExplainUtil.getAttrByPoint(thisAttr);
                subFormKey = thisAttrList.get(0);
                copyConditionList.add(item);
                if (thisSubExplainMap.isEmpty()) {
                    List<? extends FieldAttrEntity> jsonArray = thisExplainMap.get(subFormKey).getSubForm().getItems();
                    thisSubExplainMap = ExplainUtil.getExplainMapByList(jsonArray);
                    subExplainMap.put(subFormKey, thisSubExplainMap);
                }
                if (targetSubExplainMap.isEmpty()) {
                    String targetAttr = item.getAttr();
                    List<String> targetAttrList = ExplainUtil.getAttrByPoint(targetAttr);
                    if (targetAttrList.size() == 2) {
                        targetAttr = targetAttrList.get(0);
                        List<? extends FieldAttrEntity> jsonArray = targetExplainMap.get(targetAttr).getSubForm().getItems();
                        targetSubExplainMap = ExplainUtil.getExplainMapByList(jsonArray);
                    }
                }
            }
            // 目标字段为子表单字段
            if (item.getAttr().contains(FieldTypeEnum.SUB_FORM.getEsalias()) && Objects.equals(RuleValueTypeEnum.FIXED_VALUE.getType(), item.getValueType())) {
                copyConditionList.add(item);
                if (targetSubExplainMap.isEmpty()) {
                    String targetAttr = item.getAttr();
                    List<String> targetAttrList = ExplainUtil.getAttrByPoint(targetAttr);
                    if (targetAttrList.size() == 2) {
                        targetAttr = targetAttrList.get(0);
                    }
                    List<? extends FieldAttrEntity> jsonArray = targetExplainMap.get(targetAttr).getSubForm().getItems();
                    targetSubExplainMap = ExplainUtil.getExplainMapByList(jsonArray);
                }
            }
        }
        BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(operationDTO.getCorpid(), operationDTO.getThisExplain(), operationDTO.getTargetExplain(), operationDTO.getTarget(), operationDTO.getFormId(),
                operationDTO.getBusinessType(), operationDTO.getSaasMark(), operationDTO.getOperationType(), operationDTO.getFormDataMap());

        BusinessRuleInfoPojo targetBusinessRule = new BusinessRuleInfoPojo(operationDTO.getCorpid(), operationDTO.getThisExplain(), operationDTO.getTargetExplain(), operationDTO.getTarget(), operationDTO.getTarget().getFormId(),
                operationDTO.getTarget().getLinkBusinessType(), operationDTO.getTarget().getLinkSaasMark(), operationDTO.getOperationType(), operationDTO.getFormDataMap());
        // 当前字段为子表单字段时
        List<JSONObject> updateJsonList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(copyConditionList)) {
            // 根据上面的子表单，拿出数据
            JSONArray thisSubDataArray = subFormData.getJSONArray(subFormKey) == null ? new JSONArray() : subFormData.getJSONArray(subFormKey);
            for (int i = 0; i < thisSubDataArray.size(); i++) {
                JSONObject subDataJson = thisSubDataArray.getJSONObject(i);

                for (FilterConditionsPoJo filterConditionsPoJo: copyConditionList) {
                    String targetKey = filterConditionsPoJo.getAttr();
                    // 拿出对应的子表单数据
                    Integer targetFieldType = filterConditionsPoJo.getFieldType();
                    Object targetValue;

                    if (Objects.isNull(subDataJson)) {
                        continue;
                    }
                    if (Objects.equals(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), filterConditionsPoJo.getValueType())) {
                        // 动态值
                        List<String> thisAttrList = ExplainUtil.getAttrByPoint(filterConditionsPoJo.getValueAttr());
                        FieldAttrEntity targetField;
                        if (targetKey.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                            targetField = targetSubExplainMap.get(ExplainUtil.getAttrByPoint(targetKey).get(1));

                        } else {
                            targetField = targetExplainMap.get(targetKey);
                        }
                        FieldAttrEntity fieldAttrEntity;
                        if (thisAttrList.size() == 2) {

                            String thisSubKey = thisAttrList.get(1);
                            fieldAttrEntity = thisSubExplainMap.get(thisSubKey);
                            // 获取目标表单数据
                            targetValue = getTargetValue(targetKey, fieldAttrEntity, targetField, targetExplainMap, targetSubExplainMap, formDataEntityExt, subData, targetBusinessRule );

                            ConditionFieldHandler conditionFieldHandler = conditionFieldHandlerFactory.getHandlerTargetFormByFieldType(fieldAttrEntity.getFieldType());
                            Object object = conditionFieldHandler.handlerThisFormField(thisDataEntity, subDataJson, fieldAttrEntity, targetField,  businessRuleInfoPojo);
                            update = ConditionUtil.equals(targetValue, object, filterConditionsPoJo);
                        } else {
                            fieldAttrEntity = thisExplainMap.get(filterConditionsPoJo.getValueAttr());
                            targetValue = getTargetValue(targetKey, fieldAttrEntity, targetField, targetExplainMap, targetSubExplainMap, formDataEntityExt, subData, targetBusinessRule );

                            ConditionFieldHandler conditionFieldHandler = conditionFieldHandlerFactory.getHandlerTargetFormByFieldType(fieldAttrEntity.getFieldType());
                            Object object = conditionFieldHandler.handlerThisFormField(thisDataEntity, thisDataEntity.getData(), fieldAttrEntity, targetField,  businessRuleInfoPojo);
                            update = ConditionUtil.equals(targetValue, object, filterConditionsPoJo);
                        }

                    } else {
                        // 固定值
                        FieldAttrEntity targetField;
                        if (targetKey.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                            targetField = targetSubExplainMap.get(ExplainUtil.getAttrByPoint(targetKey).get(1));
                            targetFieldType = targetField.getFieldType();
                            ConditionFieldHandler conditionFieldHandler = conditionFieldHandlerFactory.getHandlerTargetFormByFieldType(targetFieldType);
                            targetValue = conditionFieldHandler.handlerThisFormField(formDataEntityExt, subData, targetField , targetField,  businessRuleInfoPojo);
                        } else {
                            targetField = targetExplainMap.get(targetKey);
                            targetFieldType = targetField.getFieldType();
                            ConditionFieldHandler conditionFieldHandler = conditionFieldHandlerFactory.getHandlerTargetFormByFieldType(targetFieldType);
                            targetValue = conditionFieldHandler.handlerThisFormField(formDataEntityExt, formDataEntityExt.getData(), targetField , targetField,  businessRuleInfoPojo);
                        }
                        // 获取当前表单的值
                        ConditionFieldHandler thisFieldCondition = conditionFieldHandlerFactory.getHandlerFixedValueByFieldType(targetFieldType);
                        Object object = thisFieldCondition.handlerFixedValue(targetField,  businessRuleInfoPojo, filterConditionsPoJo);
                        if (ExplainUtil.isCombo(filterConditionsPoJo.getFieldType())) {
                            businessRuleInfoPojo.setObject(object);
                            Object result = thisFieldCondition.handlerThisFormField(formDataEntityExt, subData, targetField, targetField, businessRuleInfoPojo);
                            update = ConditionUtil.equals(targetValue, result, filterConditionsPoJo);
                        } else {
                            update = ConditionUtil.equals(targetValue, object, filterConditionsPoJo);
                        }
                    }
                    if (!update) {
                        break;
                    }
                }
                // 上述条件校验完，则表示，子表单==子表单的条件成功
                if (update) {
                    // 可以更新的数据
                    updateJsonList.add(subDataJson);
                    break;
                }
            }
        }
        if (CollectionsUtil.isNotEmpty(updateJsonList)) {
            update = true;
        }
        return new EqualsResultPojo(update, updateJsonList, subExplainMap);
    }



    /**
     * 获取目标表单的数据
     * @param targetKey
     * @param targetField
     * @param fieldAttrEntity
     * @param targetExplainMap
     * @param targetSubExplainMap
     * @param formDataEntityExt
     * @param subData
     * @param businessRuleInfoPojo
     * @return
     * @throws XbbException
     */
    private Object getTargetValue(String targetKey,  FieldAttrEntity targetField, FieldAttrEntity fieldAttrEntity, Map<String, FieldAttrEntity> targetExplainMap,
                                  Map<String, FieldAttrEntity> targetSubExplainMap, PaasFormDataEntityExt formDataEntityExt, JSONObject subData, BusinessRuleInfoPojo businessRuleInfoPojo) throws XbbException {
        if (targetKey.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
            targetField = targetSubExplainMap.get(ExplainUtil.getAttrByPoint(targetKey).get(1));
            Integer targetFieldType = targetField.getFieldType();
            ConditionFieldHandler conditionFieldHandler = conditionFieldHandlerFactory.getHandlerTargetFormByFieldType(targetFieldType);
            return conditionFieldHandler.handlerThisFormField(formDataEntityExt, subData, targetField , fieldAttrEntity,  businessRuleInfoPojo);
        } else {
            targetField = targetExplainMap.get(targetKey);
            ConditionFieldHandler conditionFieldHandler = conditionFieldHandlerFactory.getHandlerTargetFormByFieldType(targetField.getFieldType());
            return conditionFieldHandler.handlerThisFormField(formDataEntityExt, formDataEntityExt.getData(), targetField , fieldAttrEntity,  businessRuleInfoPojo);
        }
    }

    /**
     * 获取更新的数据
     * @param thisDataEntity 当前数据
     * @param thisSubData 当前子表单数据
     * @param operationsPojo 操作方式
     * @param operationDTO
     * @return
     * @throws XbbException
     */
    public Object getUpdateResult(PaasFormDataEntity thisDataEntity, JSONObject thisSubData,
                                  OperationsPojo operationsPojo, OperationDTO operationDTO)  throws XbbException{
        Object result;
        // 拼装对象
        BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(operationDTO.getCorpid(), operationDTO.getThisExplain(), operationDTO.getTargetExplain(), operationDTO.getTarget(), operationDTO.getFormId(),
                operationDTO.getBusinessType(), operationDTO.getSaasMark(), operationDTO.getOperationType(), operationDTO.getFormDataMap());
        String targetKey = operationsPojo.getAttr();
        List<String> targetAttrList = ExplainUtil.getAttrByPoint(targetKey);
        FieldAttrEntity targetField;
        if (targetAttrList.size() == 2) {
            // 目标字段为子表单，获取子表单的字段
            targetKey = targetAttrList.get(0);
            String targetSubKey = targetAttrList.get(1);
            targetField = operationDTO.getTargetExplain().get(targetKey);
            List<? extends FieldAttrEntity> jsonArray = targetField.getSubForm().getItems();
            Map<String, FieldAttrEntity> thisSubExplainMap = ExplainUtil.getExplainMapByList(jsonArray);
            targetField = thisSubExplainMap.get(targetSubKey);
        } else {
            targetField = operationDTO.getTargetExplain().get(targetKey);
        }
        if (Objects.equals(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), operationsPojo.getValueType())) {
            // 如果是动态值，在此处处理数据
            String thisKey = operationsPojo.getValueAttr();
            FieldAttrEntity fieldAttrEntity;
            List<String> thisAttrList = ExplainUtil.getAttrByPoint(thisKey);
            if (thisAttrList.size() == 2) {
                thisKey = thisAttrList.get(0);
                String thisSubKey = thisAttrList.get(1);
                fieldAttrEntity = operationDTO.getThisExplain().get(thisKey);
                List<? extends FieldAttrEntity> jsonArray = fieldAttrEntity.getSubForm().getItems();
                Map<String, FieldAttrEntity> thisSubExplainMap = ExplainUtil.getExplainMapByList(jsonArray);
                fieldAttrEntity = thisSubExplainMap.get(thisSubKey);
            } else {
                fieldAttrEntity = operationDTO.getThisExplain().get(thisKey);
                thisSubData = thisDataEntity.getData();
            }
            // 操作方式的工厂类处理当前字段
            OperatorFieldHandler operatorFieldHandler = operatorFieldHandlerFactory.getHandlerByFieldType(fieldAttrEntity.getFieldType());

            Object value = operatorFieldHandler.handlerThisFormField(thisDataEntity, thisSubData, fieldAttrEntity, businessRuleInfoPojo);
            businessRuleInfoPojo.setObject(value);
            // 操作方式的工厂类处理目标字段
            OperatorFieldHandler  operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerTargetFormByFieldType(targetField.getFieldType());
            result = operatorTargetFieldHandler.handlerTargetFormField(thisDataEntity, thisSubData , fieldAttrEntity, targetField, businessRuleInfoPojo, operationsPojo);
        } else {
            // 固定值的操作
            OperatorFieldHandler operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerFixedValueByFieldType(targetField.getFieldType());
            result = operatorTargetFieldHandler.handlerFixedValue(targetField, businessRuleInfoPojo, operationsPojo);
        }
        return result;
    }



    /**
     * 根据字段类型获取显示的值
     * @param fieldAttrEntity 字段信息
     * @param explainMap 字段容器
     * @param data
     * @param formId
     * @param businessType
     * @param corpid
     * @return
     * @throws XbbException
     */
    public Object getDataByFieldType(FieldAttrEntity fieldAttrEntity, Map<String, FieldAttrEntity> explainMap, PaasFormDataEntity formDataEntity, JSONObject data,
                                     Long formId, Integer businessType, String corpid, BusinessRuleInfoPojo businessRuleInfoPojo) throws XbbException {
        if (Objects.isNull(fieldAttrEntity)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
        }
        Object value = null;
        Integer fieldType = fieldAttrEntity.getFieldType();
        String attr = fieldAttrEntity.getAttr();
        FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
        switch (fieldTypeEnum) {
            case RADIO_GROUP:
            case COMBO:
                Object comboValue = "";
                // 1、如果本表单字段是下拉框、下拉复选、单选按钮、复选按钮，需要先根据value取出text，放入data中；
                // 2、在下方取出data的text，然后拿到对应的value，之后在根据value去查询对应的数据；
                if (Objects.equals(ComboTypeEnum.CUSTOM.getType(), fieldAttrEntity.getComboType())) {
                    List<ItemPoJo> itemPoJos = proFormHelp.getItem(fieldAttrEntity, businessType, corpid, formId);
                    fieldAttrEntity.setItems(itemPoJos);
                    comboValue = ItemUtil.getCustomItemList(fieldAttrEntity, data);
                } else {
                    comboValue = data.get(attr);
                }
                if (Objects.isNull(comboValue)) {
                    comboValue = "";
                }
                if (comboValue instanceof List) {
                    value = JSON.toJSONString(comboValue);
                } else {
                    value = comboValue;
                }
                value = "\""+ value + "\"";
                break;
            case STAGE_THRUSTER:
                // 如果阶段推进器存在数据，则获取这个数据所在的版本，如果没有则获取当前启用的版本
                List<ItemPoJo> list = proFormHelp.getEditStageComboItems(fieldAttrEntity, businessRuleInfoPojo.getSaasMark(), businessType, corpid, formId, data);
                fieldAttrEntity.setItems(list);
                // 返回code对应的text值
                comboValue = ItemUtil.getCustomItemList(fieldAttrEntity, data);
                if (Objects.isNull(comboValue) || StringUtil.isEmpty(comboValue.toString())) {
                    return "";
                }
                return "\""+ comboValue + "\"";
            case CHECKBOX_GROUP:
            case COMBO_CHECK:
                Object comboCheckValue = "";
                // 1、如果本表单字段是下拉框、下拉复选、单选按钮、复选按钮，需要先根据value取出text，放入data中；
                // 2、在下方取出data的text，然后拿到对应的value，之后在根据value去查询对应的数据；
                if (Objects.equals(ComboTypeEnum.CUSTOM.getType(), fieldAttrEntity.getComboType())) {
                    comboCheckValue = ItemUtil.getCustomItemList(fieldAttrEntity, data);
                } else {
                    comboCheckValue = data.get(attr);
                }
                if (Objects.isNull(comboCheckValue)) {
                    comboCheckValue =  new ArrayList<>();
                }
                value = JSON.toJSONString(comboCheckValue);
                break;
            case ADDRESS:
                Object address = data.get(attr);
                if (Objects.isNull(address)){
                    JSONObject addressJson = new JSONObject();
                    addressJson.put(BusinessConstant.PROVINCE, "");
                    addressJson.put(BusinessConstant.CITY, "");
                    addressJson.put(BusinessConstant.DISTRICT, "");
                    addressJson.put(BusinessConstant.ADDRESS, "");
                    address = addressJson;
                }
                value = JSON.toJSONString(address);
                break;
            case TEXT:
            case TEXTAREA:
                value = data.get(attr);
                if (Objects.isNull(value)) {
                    value = "";
                }
                value = "\""+ value + "\"";
                break;
            case DATETIME:
                value = data.get(attr);
                if (Objects.isNull(value)) {
                    value = 0L;
                }
                break;
            case DATAID:
                value = formDataEntity.getId();
                break;
            case NUM:
                value = data.get(attr);
                if (Objects.isNull(value)) {
                    value = 0;
                }
                value = MathUtil.scientificNotation(value);
                break;
            case USER_GROUP:
            case DEPT_GROUP:
                value = JSON.toJSONString(data.get(attr));
                break;
            case OWNERID:
                if (UserTeamEnum.hasTeam(businessType)) {
                    Map<Long, List<String>> ownerIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    Map<Long, List<String>> coUserIdMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    List<Long> idIn = new ArrayList<>();
                    idIn.add(formDataEntity.getId());
                    formDataFormExplainHelper.getUserIdMap(idIn, formDataEntity.getCorpid(), businessType, false, ownerIdMap, coUserIdMap);

                    List<String> ownerId = ownerIdMap.get(formDataEntity.getId());
                    if (Objects.isNull(ownerId) || ownerId.isEmpty()) {
                        return null;
                    }
                    return JSON.toJSONString(ownerId);
                } else {
                    return JSON.toJSONString(Collections.singletonList(formDataEntity.getOwnerId()));
                }
            case IMAGE:
                value = JSON.toJSONString(data.get(attr));
                break;
            case USER:
                value = data.getString(attr);
                if (Objects.nonNull(value)) {
                    value = "\""+ value + "\"";
                }
                break;
            case SERIALNO:
                value = formDataEntity.getSerialNo();
                if (Objects.nonNull(value)) {
                    value = "\""+ value + "\"";
                }
                break;
            default:
                value = data.get(attr);
                break;
        }
        return value;
    }

    /**
     * 根据value值，去获取下拉框、单选按钮和下拉复选、复选框等的值
     * @return
     */
    public Object getTargetDataByFieldType(Map<String, FieldAttrEntity> explainMap, Object value, OperationsPojo operationsPojo, FieldAttrEntity targetField,
                                           RuleTargetPojo ruleTargetPojo, String corpid, BusinessRuleInfoPojo businessRuleInfoPojo) throws XbbException {
        Integer fieldType = targetField.getFieldType();
        if (Objects.isNull(value) && Objects.equals(FieldTypeEnum.NUM.getType(), fieldType)) {
            return 0;
        }
        if (Objects.isNull(value)) {
            return null;
        }
        Object result = null;
        try {
            FieldTypeEnum fieldTypeEnum = FieldTypeEnum.getFieldTypeEnum(fieldType);
            Integer businessType = ruleTargetPojo.getLinkBusinessType();
            Long formId = ruleTargetPojo.getFormId();
            switch (fieldTypeEnum) {
                case RADIO_GROUP:
                case COMBO:
                    //  接上面的第2点在这里取出data的text，然后拿到对应的value，之后在根据value去查询对应的数据；
                    if (Objects.equals(ComboTypeEnum.CUSTOM.getType(), targetField.getComboType())) {
                        List<ItemPoJo> itemPoJos = proFormHelp.getItem(targetField, businessType, corpid, formId);
                        targetField.setItems(itemPoJos);
                        result = ItemUtil.getCustomItemValue(targetField, value.toString());
                    } else {
                        result = value;
                    }
                    break;
                case CHECKBOX_GROUP:
                case COMBO_CHECK:
                    // 复选框/下拉复选
                    List<String> list = JSON.parseArray(JSON.toJSONString(value), String.class);
                    if (Objects.equals(ComboTypeEnum.CUSTOM.getType(), targetField.getComboType())) {
                        result = ItemUtil.getCustomItemList(targetField, list);
                    } else {
                        result = list;
                    }
                    break;
                case USER:
                    String user = JSON.toJSONString(value);
                    LOGGER.error("complexFormatHelp.user：" + user);
                    if (RegexUtil.squareBrackets(user)) {
                        try {
                            List<String> userList = JSON.parseArray(user, String.class);
                            if (CollectionsUtil.isNotEmpty(userList)) {
                                result = userList.get(0);
                            }
                        } catch (Exception e) {
                            throw new XbbException(BusinessRuleErrorCodeEnum.API_ERROR_261007);
                        }
                    } else {
                        result = value.toString();
                    }
                    break;
                case USER_GROUP:
                    List<String> userList = JSON.parseArray(JSON.toJSONString(value), String.class);
                    result = userList;
                    break;
                case DEPT:
                    if (!RegexUtil.isInteger(value.toString())) {
                        throw new XbbException(ProErrorCodeEnum.API_ERROR_260017);
                    }
                    result = Long.valueOf(value.toString());
                    break;
                case DEPT_GROUP:
                    List<Long> departmentList = JSON.parseArray(JSON.toJSONString(value), Long.class);
                    result = departmentList;
                    break;
                case ADDRESS:
                    if (value instanceof String && !value.toString().contains(BusinessConstant.PROVINCE)) {
                        // 字符串表示是固定值，需要对其进行解析
                        // toString()用于去掉手动加的引号
                        JSONObject address = AddressHelp.getAddress(value.toString(), targetField);
                        result = address;
                    } else {
                        JSONObject address = JSON.parseObject(JSON.toJSONString(value));
                        if (Objects.equals(0, targetField.getShowDetailAddress())) {
                            address.put(BusinessConstant.ADDRESS, "");
                        }
                        result = address;
                    }
                    break;
                case DATETIME:
                    if (Objects.equals(value, 0L) || Objects.equals(value, 0) || StringUtil.isEmpty(value.toString()) || Objects.equals(value.toString(),Constant.ZERO_STRING)) {
                        return null;
                    }
                    Long time = Long.valueOf(value.toString()) * 1000L;
                    if (Objects.equals(DateTimeEnum.DATETIME.getType(), targetField.getDateType())) {
                        result = DateTimeUtil.getInt(DateTimeUtil.getString(time, DateTimeUtil.SDF), DateTimeUtil.SDFYMDHM);
                    } else {
                        result = DateTimeUtil.getInt(DateTimeUtil.getString(time, DateTimeUtil.SDF), DateTimeUtil.SDFDate);
                    }
                    break;
                case LINK_DATA:
                    if (value instanceof String) {
                        value = Long.valueOf(value.toString());
                    }
                    result = value;
                    break;
                case LINK_DATA_MULTI:
                    List<Long> linkDataList = new ArrayList<>();
                    // 将当前表单的关联数据赋给目标表单的关联数据多选
                    if (value instanceof String || value instanceof Number) {
                        Long linkData = Long.valueOf(value.toString());
                        linkDataList.add(linkData);
                    }
                    // 将当前表单的关联数据赋给目标表单的关联数据多选
                    if (value instanceof List || value.getClass().isArray()) {
                        linkDataList = JSON.parseArray(JSON.toJSONString(value), Long.class);
                    }
                    result = linkDataList;
                    break;
                case NUM:
                    if (value instanceof String) {
                        if (RegexUtil.isInteger(value.toString())) {
                            long num = Long.valueOf(value.toString());
                            if (num <= Integer.MAX_VALUE && num >= Integer.MIN_VALUE) {
                                value = (int) num;
                            } else {
                                value = num;
                            }
                        } else {
                            value = Double.valueOf(value.toString());
                        }
                    }
                    Integer accuracy = targetField.getAccuracy();
                    if (Objects.equals(1, targetField.getIntegerOnly())) {
                        accuracy = 0;
                    }
                    result = MathUtil.ceil(value, accuracy);
                    break;
                case IMAGE:
                    Integer onlyOne = targetField.getOnlyOneFile();
                    if (Objects.equals(1, onlyOne)) {
                        // 当目标表单的图片字段为仅允许上传一张，而当前表单的图片字段为可上传多张时，此时将当前表单中图片字段中的第一张图赋值给目标表单的图片字段。
                        //当目标表单的附件为仅允许上传一个，而当前表单的附件字段为可上传多个文件时，此时将当前表单中附件字段中的第一个文件赋值给目标表单的附件字段。
                        List<String> jsonArray = JSON.parseArray(JSON.toJSONString(value), String.class);
                        if (Objects.isNull(jsonArray) || jsonArray.isEmpty()) {
                            return null;
                        }
                        result = Arrays.asList(jsonArray.get(0));
                    } else {
                        result = JSON.parseArray(JSON.toJSONString(value), String.class);
                    }
                    break;
                default:
                    if (String.valueOf(value).contains(SymbolConstant.HYPERTEXT_SPACE)) {
                        // 替换掉空格
                        return String.valueOf(value).replaceAll(SymbolConstant.HYPERTEXT_SPACE, " ");
                    }
                    result = value;
                    break;
            }
        } catch (XbbException e) {
            throw e;
        }catch (Exception e) {
            LOGGER.error("value= "+ value + "；complexFormatHelp.getTargetDataByFieldType获取目标表单字段数据报错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return result;
    }

    /**
     * 获取添加的数据
     * @param operationDTO
     * @return
     * @throws XbbException
     */
    public JSONArray getInsertList(OperationDTO operationDTO) throws XbbException {
        JSONArray dataList = new JSONArray();
        try {
            List<OperationsPojo> operationList = operationDTO.getOperations();
            PaasFormDataEntity thisDataEntity = operationDTO.getPaasFormDataEntity();
            JSONObject data = thisDataEntity.getData();
            Map<String, FieldAttrEntity> targetExplainMap = operationDTO.getTargetExplain();
            Map<String, FieldAttrEntity> thisExplainMap = operationDTO.getThisExplain();
            JSONObject result = new JSONObject();
            BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(operationDTO.getCorpid(), operationDTO.getThisExplain(), operationDTO.getTargetExplain(), operationDTO.getTarget(), operationDTO.getFormId(),
                    operationDTO.getBusinessType(), operationDTO.getSaasMark(), operationDTO.getOperationType(), operationDTO.getFormDataMap());
            Map<String, JSONArray> subResultMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Integer maxSize = 0;
            Map<String, Map<String, FieldAttrEntity>> targetSubExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String, Map<String, FieldAttrEntity>> thisSubExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String, OperationsPojo> targetSubOperator = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String, OperationsPojo> operatorMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (OperationsPojo item : operationList) {
                String targetAttr = item.getAttr();
                List<String> targetAttrList = ExplainUtil.getAttrByPoint(targetAttr);
                if (targetAttrList.size() == 2) {
                    targetAttr = targetAttrList.get(0);
                    if (!targetSubExplainMap.containsKey(targetAttr)) {
                        FieldAttrEntity targetField = targetExplainMap.get(targetAttr);
                        List<? extends FieldAttrEntity> jsonArray = targetField.getSubForm().getItems();
                        // 子表单会存在多个，所以需要这么存储
                        targetSubExplainMap.put(targetAttr, ExplainUtil.getExplainMapByList(jsonArray));
                    }
                    targetSubOperator.put(item.getAttr(), item);
                }
                operatorMap.put(targetAttr, item);
                if (Objects.equals(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), item.getValueType())) {
                    String thisAttr = item.getValueAttr();
                    List<String> thisAttrList = ExplainUtil.getAttrByPoint(thisAttr);
                    if (thisAttrList.size() == 2) {
                        thisAttr = thisAttrList.get(0);
                        FieldAttrEntity thisField = thisExplainMap.get(thisAttr);
                        List<? extends FieldAttrEntity> jsonArray = thisField.getSubForm().getItems();
                        if (!thisSubExplainMap.containsKey(thisAttr)) {
                            thisSubExplainMap.put(thisAttr, ExplainUtil.getExplainMapByList(jsonArray));
                        }
                    }
                }
            }

            Iterator<String> operatorIterator = operatorMap.keySet().iterator();
            while (operatorIterator.hasNext()) {
                OperationsPojo item = operatorMap.get(operatorIterator.next());
                String targetAttr = item.getAttr();
                List<String> targetAttrList = ExplainUtil.getAttrByPoint(targetAttr);
                if (targetAttrList.size() == 2) {
                    targetAttr = targetAttrList.get(0);
                }
                FieldAttrEntity targetField = targetExplainMap.get(targetAttr);
                if (Objects.isNull(targetField)) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
                }
                String thisAttr = item.getValueAttr();
                List<String> thisAttrList = ExplainUtil.getAttrByPoint(thisAttr);
                Boolean thisIsSubForm = false;
                FieldAttrEntity thisField = thisExplainMap.get(thisAttr);

                if (thisAttrList.size() == 2) {
                    thisAttr = thisAttrList.get(0);
                    thisField = thisExplainMap.get(thisAttr);
                    if (Objects.isNull(thisField)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
                    }
                    thisIsSubForm = ExplainUtil.isSubForm(thisField.getFieldType());
                }
                Boolean targetIsSubForm = ExplainUtil.isSubForm(targetField.getFieldType());

                if (targetIsSubForm && thisIsSubForm) {
                    // 子字段赋值子字段
                    JSONArray subDataArray = new JSONArray();
                    if (Objects.nonNull(thisDataEntity.getSubFormData())) {
                        subDataArray = thisDataEntity.getSubFormData().getJSONArray(thisAttr);
                    }
                    if (Objects.nonNull(subDataArray)) {
                        JSONArray resultArray = new JSONArray();
                        for (int i = 0; i < subDataArray.size(); i++) {
                            Iterator<String> subOperatorIterator = targetSubOperator.keySet().iterator();
                            JSONObject resultJson = new JSONObject();
                            while (subOperatorIterator.hasNext()) {
                                String key = subOperatorIterator.next();
                                String subKey = "";
                                String parentKey = key;
                                List<String> keyList = ExplainUtil.getAttrByPoint(key);
                                if (keyList.size() == BasicConstant.TWO) {
                                    parentKey = keyList.get(0);
                                    subKey = keyList.get(1);
                                }
                                Map<String, FieldAttrEntity> targetSubMap = targetSubExplainMap.get(parentKey);
                                FieldAttrEntity targetSubField = targetSubMap.get(subKey);
                                OperationsPojo operationsPojo = targetSubOperator.get(key);
                                if (Objects.equals(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), operationsPojo.getValueType())) {
                                    JSONObject jsonObject = subDataArray.getJSONObject(i);
                                    thisAttrList = ExplainUtil.getAttrByPoint(operationsPojo.getValueAttr());
                                    Map<String, FieldAttrEntity> thisSubMap = thisSubExplainMap.get(thisAttrList.get(0));
                                    FieldAttrEntity thisSubField = thisSubMap.get(thisAttrList.get(1));
                                    if (Objects.isNull(thisSubField)) {
                                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
                                    }
                                    OperatorFieldHandler operatorFieldHandler = operatorFieldHandlerFactory.getHandlerByFieldType(thisSubField.getFieldType());
                                    Object comboText = operatorFieldHandler.handlerThisFormField(thisDataEntity, jsonObject, thisSubField, businessRuleInfoPojo);
                                    businessRuleInfoPojo.setObject(comboText);
                                    OperatorFieldHandler operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerTargetFormByFieldType(targetSubField.getFieldType());
                                    Object value = operatorTargetFieldHandler.handlerTargetFormField(thisDataEntity, jsonObject, thisSubField, targetSubField, businessRuleInfoPojo, operationsPojo);
                                    resultJson.put(targetSubField.getAttr(), value);

                                } else {
                                    // 固定值
                                    if (Objects.isNull(operationsPojo.getValue())) {
                                        continue;
                                    }
                                    OperatorFieldHandler operatorFieldHandler = operatorFieldHandlerFactory.getHandlerFixedValueByFieldType(targetSubField.getFieldType());
                                    Object text = operatorFieldHandler.handlerFixedValue(targetSubField, businessRuleInfoPojo, operationsPojo);
                                    resultJson.put(targetSubField.getAttr(), text);
                                }
                            }
                            resultArray.add(resultJson);
                        }
                        result.put(targetAttr, resultArray);
                    }
                } else if (targetIsSubForm && (!thisIsSubForm || Objects.equals(RuleValueTypeEnum.FIXED_VALUE.getType(), item.getValueType()))) {
                    // 主字段赋值子表单字段，或者固定值赋值子表单字段
                    Iterator<String> subOperatorIterator = targetSubOperator.keySet().iterator();
                    JSONObject resultJson = new JSONObject();
                    JSONArray resultJsonArray = new JSONArray();
                    while (subOperatorIterator.hasNext()) {
                        String key = subOperatorIterator.next();
                        String subKey = "";
                        String parentKey = key;
                        List<String> keyList = ExplainUtil.getAttrByPoint(key);
                        if (keyList.size() == BasicConstant.TWO) {
                            parentKey = keyList.get(0);
                            subKey = keyList.get(1);
                        }
                        OperationsPojo operationsPojo = targetSubOperator.get(key);
                        if (Objects.equals(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), operationsPojo.getValueType())) {
                            thisField = thisExplainMap.get(operationsPojo.getValueAttr());
                            if (Objects.isNull(thisField)) {
                                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
                            }
                            Map<String, FieldAttrEntity> targetSubMap = targetSubExplainMap.get(parentKey);
                            FieldAttrEntity targetSubField = targetSubMap.get(subKey);
                            OperatorFieldHandler operatorFieldHandler = operatorFieldHandlerFactory.getHandlerByFieldType(thisField.getFieldType());
                            Object comboText = operatorFieldHandler.handlerThisFormField(thisDataEntity, data, thisField, businessRuleInfoPojo);
                            businessRuleInfoPojo.setObject(comboText);
                            OperatorFieldHandler operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerTargetFormByFieldType(targetSubField.getFieldType());
                            Object value = operatorTargetFieldHandler.handlerTargetFormField(thisDataEntity, data, thisField, targetSubField, businessRuleInfoPojo, operationsPojo);
                            resultJson.put(targetSubField.getAttr(), value);

                        } else {
                            Map<String, FieldAttrEntity> targetSubMap = targetSubExplainMap.get(parentKey);
                            FieldAttrEntity targetSubField = targetSubMap.get(subKey);
                            if (Objects.isNull(item.getValue())) {
                                continue;
                            }
                            // 固定值的操作
                            OperatorFieldHandler operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerFixedValueByFieldType(targetSubField.getFieldType());
                            Object value = operatorTargetFieldHandler.handlerFixedValue(targetSubField, businessRuleInfoPojo, operationsPojo);
                            resultJson.put(targetSubField.getAttr(), value);
                        }
                    }
                    resultJsonArray.add(resultJson);
                    result.put(targetAttr, resultJsonArray);
                } else if (!targetIsSubForm && thisIsSubForm) {
                    // 子字段赋值给主字段
                    JSONArray subDataArray = new JSONArray();
                    if (Objects.nonNull(thisDataEntity.getSubFormData())) {
                        subDataArray = thisDataEntity.getSubFormData().getJSONArray(thisAttr);
                    }
                    if (Objects.nonNull(subDataArray)) {
                        JSONArray subResultList = new JSONArray();
                        int length = subDataArray.size();
                        if (length > maxSize) {
                            maxSize = length;
                        }
                        Map<String, FieldAttrEntity> thisSubMap = thisSubExplainMap.get(thisAttrList.get(0));
                        FieldAttrEntity thisSubField = thisSubMap.get(thisAttrList.get(1));
                        if (Objects.isNull(thisSubField)) {
                            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
                        }
                        for (int i = 0; i < subDataArray.size(); i++) {
                            JSONObject resultJson = new JSONObject();
                            if (Objects.equals(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), item.getValueType())) {
                                JSONObject jsonObject = subDataArray.getJSONObject(i);
                                OperatorFieldHandler operatorFieldHandler = operatorFieldHandlerFactory.getHandlerByFieldType(thisSubField.getFieldType());
                                Object comboText = operatorFieldHandler.handlerThisFormField(thisDataEntity, jsonObject, thisSubField, businessRuleInfoPojo);
                                businessRuleInfoPojo.setObject(comboText);
                                OperatorFieldHandler operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerTargetFormByFieldType(targetField.getFieldType());
                                Object value = operatorTargetFieldHandler.handlerTargetFormField(thisDataEntity, jsonObject, thisSubField, targetField, businessRuleInfoPojo, item);
                                resultJson.put(targetAttr, value);
                            } else {
                                if (Objects.isNull(item.getValue())) {
                                    continue;
                                }
                                // 固定值的操作
                                OperatorFieldHandler operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerFixedValueByFieldType(targetField.getFieldType());
                                Object value = operatorTargetFieldHandler.handlerFixedValue(targetField, businessRuleInfoPojo, item);
                                resultJson.put(targetAttr, value);
                            }
                            subResultList.add(resultJson);
                        }
                        subResultMap.put(targetAttr, subResultList);
                    }
                } else if (Objects.equals(RuleValueTypeEnum.DYNAMIC_VALUE.getType(), item.getValueType())) {
                    if (Objects.isNull(thisField)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
                    }
                    OperatorFieldHandler operatorFieldHandler = operatorFieldHandlerFactory.getHandlerByFieldType(thisField.getFieldType());
                    Object comboText = operatorFieldHandler.handlerThisFormField(thisDataEntity, data, thisField, businessRuleInfoPojo);
                    businessRuleInfoPojo.setObject(comboText);
                    OperatorFieldHandler operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerTargetFormByFieldType(targetField.getFieldType());
                    Object value = operatorTargetFieldHandler.handlerTargetFormField(thisDataEntity, data, thisField, targetField, businessRuleInfoPojo, item);
                    // 主字段赋值主字段
                    result.put(targetAttr, value);
                } else {
                    if (Objects.isNull(item.getValue())) {
                        continue;
                    }
                    // 固定值的操作
                    OperatorFieldHandler operatorTargetFieldHandler = operatorFieldHandlerFactory.getHandlerFixedValueByFieldType(targetField.getFieldType());
                    Object value = operatorTargetFieldHandler.handlerFixedValue(targetField, businessRuleInfoPojo, item);
                    result.put(targetAttr, value);
                }
            }
            if (subResultMap.size() > 0) {
                for (int i = 0; i < maxSize; i++) {
                    JSONObject dataJson = new JSONObject();
                    dataJson.putAll(result);
                    Iterator<String> iterator = subResultMap.keySet().iterator();
                    while (iterator.hasNext()) {
                        String key = iterator.next();
                        int length = subResultMap.get(key).size();
                        if (i < length) {
                            // 避免溢出
                            dataJson.put(key, subResultMap.get(key).getJSONObject(i).get(key));
                        }
                    }
                    dataList.add(dataJson);
                }
            } else {
                dataList.add(result);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("ComplexFormatHelp.getInsertList 获取需要新增的数据报错：corpid = " + operationDTO.getCorpid(), e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return dataList;
    }

    /**
     * 公式级添加数据
     * @param operationDTO
     * @return
     * @throws XbbException
     */

    public JSONArray getInsertListByFormula(OperationDTO operationDTO) throws XbbException {
        JSONArray dataList = new JSONArray();
        try {
            List<OperationsPojo> operationList = operationDTO.getOperations();
            Map<String, FieldAttrEntity> targetExplainMap = operationDTO.getTargetExplain();

            Map<String, JSONArray> dataMap = new HashMap<>(operationList.size());
            Map<String, Map<String, JSONArray>> allSubDataMap = new HashMap<>(operationList.size());
            Iterator<OperationsPojo> iterator = operationList.iterator();
            Map<String, Integer> subMaxMap = new HashMap<>(operationList.size());
            // 默认一行，因为可能只有子表单数据
            Integer maxSize = 1;
            // 解开操作方式
            while (iterator.hasNext()) {
                OperationsPojo item = iterator.next();
                String targetAttr = item.getAttr();
                List<String> targetAttrList = ExplainUtil.getAttrByPoint(targetAttr);
                FieldAttrEntity targetField = targetExplainMap.get(targetAttr);
                String targetSubAttr = "";
                if (targetAttrList.size() == 2) {
                    targetAttr = targetAttrList.get(0);
                    targetSubAttr = targetAttrList.get(1);
                    targetField = targetExplainMap.get(targetAttr);
                }
                // 公式解析，返回得到的结果集
                JSONArray dataJson = complexFormatOnlyAdd(operationDTO, item);
                if (Objects.isNull(dataJson) ) {
                    continue;
                }
                if (ExplainUtil.isSubForm(targetField.getFieldType())) {
                    if (allSubDataMap.containsKey(targetAttr)) {
                        Map<String, JSONArray> subDataMap = allSubDataMap.get(targetAttr);
                        subDataMap.put(targetSubAttr, dataJson);
                        allSubDataMap.put(targetAttr, subDataMap);
                        Integer subMax = subMaxMap.get(targetAttr);
                        if (dataJson.size()>subMax) {
                            subMaxMap.put(targetAttr, dataJson.size());
                        }
                    } else {
                        Map<String, JSONArray> subDataMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        subDataMap.put(targetSubAttr, dataJson);
                        allSubDataMap.put(targetAttr, subDataMap);
                        subMaxMap.put(targetAttr, dataJson.size());
                    }
                } else {
                    dataMap.put(targetAttr, dataJson);
                    if (dataJson.size() > maxSize) {
                        maxSize = dataJson.size();
                    }
                }
            }
            if (!allSubDataMap.isEmpty()) {
                Iterator<String> allSubIterator = allSubDataMap.keySet().iterator();
                while (allSubIterator.hasNext()) {
                    String key = allSubIterator.next();
                    Integer length = subMaxMap.get(key);
                    Map<String, JSONArray> subDataMap = allSubDataMap.get(key);
                    JSONArray subDataArray = new JSONArray();
                    for (int i = 0; i < length; i++) {
                       Iterator<String> subIterator = subDataMap.keySet().iterator();
                        JSONObject jsonObject = new JSONObject();
                        while (subIterator.hasNext()) {
                           String subKey = subIterator.next();
                           JSONArray jsonArray = subDataMap.get(subKey);
                           if (Objects.nonNull(jsonArray) && i<jsonArray.size()) {
                               jsonObject.put(subKey, jsonArray.getJSONObject(i).get(subKey));
                           }
                       }
                       subDataArray.add(jsonObject);
                    }
                    dataMap.put(key, subDataArray);
                }
            }
            // 循环行数
            for (int i = 0; i < maxSize; i++) {
                Iterator<String> dataIterator = dataMap.keySet().iterator();
                JSONObject result = new JSONObject();
                while(dataIterator.hasNext()) {
                    // 循环数据
                    String key = dataIterator.next();
                    JSONArray jsonArray = dataMap.get(key);
                    int length = jsonArray.size();
                    if (key.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                        result.put(key, dataMap.get(key));
                    } else if (i < length) {
                        // 避免溢出
                        if (Objects.nonNull(dataMap.get(key)) && Objects.nonNull(dataMap.get(key).getJSONObject(i))) {
                            result.put(key, dataMap.get(key).getJSONObject(i).get(key));
                        }
                    } else if (Objects.nonNull(dataMap.get(key)) && length > 0){
                        result.put(key, dataMap.get(key).getJSONObject(length-1).get(key));
                    }
                }
                dataList.add(result);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("ComplexFormatHelp.getInsertList 获取需要新增的数据报错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return dataList;
    }

    /**
     * 插入时的公式解析，返回得到的结果集
     * @param operationDTO
     * @param operationsPojo
     * @return [{"text_1": ""}] 或者 [{"subForm_1.text_1": ""}]
     * @throws XbbException
     */
    public JSONArray complexFormatOnlyAdd(OperationDTO operationDTO, OperationsPojo operationsPojo) throws XbbException {
        JSONArray resultJsonArray = new JSONArray();
        try {
            String corpid = operationDTO.getCorpid();
            Integer businessType = operationDTO.getBusinessType();
            // 拼装对象
            BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(corpid, operationDTO.getThisExplain(), operationDTO.getTargetExplain(), operationDTO.getTarget(), operationDTO.getFormId(), businessType, operationDTO.getSaasMark(), operationDTO.getOperationType(), operationDTO.getFormDataMap());
            Map <String, FieldAttrEntity> thisExplainMap = operationDTO.getThisExplain();
            Map <String, FieldAttrEntity> targetExplainMap = operationDTO.getTargetExplain();
            PaasFormDataEntity thisDataEntity = operationDTO.getPaasFormDataEntity();
            JSONObject thisData = thisDataEntity.getData();
            Long thisFormId = thisDataEntity.getFormId();
            RuleTargetPojo ruleTargetPojo = operationDTO.getTarget();
            Long targetFormId = ruleTargetPojo.getFormId();
            Integer targetBusinessType = ruleTargetPojo.getLinkBusinessType();
            String formula = operationsPojo.getFormulaInfo().getFormula();
            String[] formulaArray = RegexUtil.getFormulaAttr(formula);
            String targetAttr = operationsPojo.getAttr();
            List<String> targetAttrList = ExplainUtil.getAttrByPoint(targetAttr);
            FieldAttrEntity targetField = targetExplainMap.get(targetAttr);
            Map<String, FieldAttrEntity> targetSubExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            if (targetAttrList.size() == 2) {
                String attr = targetAttrList.get(0);
                targetField = targetExplainMap.get(attr);
            }
            if (Objects.isNull(targetField)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
            }
            if (formula.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                // 公式含有子表单
                resultJsonArray = getSubDataByFormulaInsert(targetField, formulaArray, operationDTO, operationsPojo);
            } else {
                if (ExplainUtil.isSubForm(targetField.getFieldType())) {
                    String targetSubAttr = targetAttrList.get(1);
                    List<? extends FieldAttrEntity> jsonArray = targetField.getSubForm().getItems();
                    targetSubExplainMap = ExplainUtil.getExplainMapByList(jsonArray);
                    targetField = targetSubExplainMap.get(targetSubAttr);
                    if (Objects.isNull(targetField)) {
                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.THIS_EXPLAIN_NOT_EXIST);
                    }
                    targetAttr = targetField.getAttr();
                }
                // 不含子表单的本表单字段计算
                for (int i = 0; i < formulaArray.length; i++) {
                    String formulaAttr = formulaArray[i];
                    Object value = null;
                    if (formulaAttr.contains("self.")) {
                        // 本表单的字段操作
                        String attr = formulaAttr.replaceAll("self.", "").replaceAll("[\\{\\}]", "");
                        value = getData(attr, thisExplainMap, thisDataEntity, thisData, thisFormId, businessType, corpid, businessRuleInfoPojo);
                    } else if (RegexUtil.isStartWithNumber(formulaAttr) || formulaAttr.contains("workOrder_")) {
                        // 目标表单
                        Integer startNum = formulaAttr.indexOf(".")+1;
                        Integer length = formulaAttr.length();
                        String attr = formulaAttr.substring(startNum, length).replaceAll("[\\{\\}]", "");
                        if (attr.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {

                            List<String> attrList = ExplainUtil.getAttrByPoint(attr);
                            attr = attrList.get(1);
                            value = getData(attr, targetSubExplainMap, new PaasFormDataEntity(), new JSONObject(), targetFormId, targetBusinessType, corpid, businessRuleInfoPojo);
                        } else {
                            value = getData(attr, targetExplainMap, new PaasFormDataEntity(), new JSONObject(), targetFormId, targetBusinessType, corpid, businessRuleInfoPojo);
                        }

                    } else if (formulaAttr.contains("user.")) {
                        value = formulaAttr.replace("user.", "").replaceAll("[\\{\\}]", "");
                    } else if (formulaAttr.contains("dept.")) {
                        value = formulaAttr.replace("dept.", "").replaceAll("[\\{\\}]", "");
                    }
                    if (Objects.isNull(value)) {
                        formula = null;
                        break;
                    } else {
                        formula = formula.replace(formulaAttr, value.toString());
                    }
                }
                Object value = functionService.expressRun(formula, new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
                value = PaasStringUtil.replaceQuotes(value);
                value = getTargetDataByFieldType(targetExplainMap, value, operationsPojo, targetField, ruleTargetPojo, corpid, businessRuleInfoPojo);
                JSONObject result = new JSONObject();
                result.put(targetAttr, value);
                resultJsonArray.add(result);
            }
        } catch (XbbException e) {
            throw e;
        } catch (Exception e) {
            LOGGER.error("ComplexFormatHelp.complexFormat 公式解析报错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return resultJsonArray;
    }

    /**
     * 获取子表单相关解释容器，只在插入的时候调用这个
     * @param targetField 子表单内字段
     * @param formulaArray 公式
     * @param operationDTO
     * @return
     */
    private JSONArray getSubDataByFormulaInsert(FieldAttrEntity targetField, String[] formulaArray, OperationDTO operationDTO, OperationsPojo operationsPojo) throws XbbException {
        Map<String, Map<String, FieldAttrEntity>> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map <String, FieldAttrEntity> thisExplainMap = operationDTO.getThisExplain();
        Map <String, FieldAttrEntity> targetExplainMap = operationDTO.getTargetExplain();
        PaasFormDataEntity thisDataEntity = operationDTO.getPaasFormDataEntity();
        JSONObject thisData = thisDataEntity.getData();
        RuleTargetPojo ruleTargetPojo = operationDTO.getTarget();
        Long targetFormId = ruleTargetPojo.getFormId();
        Integer targetBusinessType = ruleTargetPojo.getLinkBusinessType();
        Integer businessType = operationDTO.getBusinessType();
        Long thisFormId = thisDataEntity.getFormId();
        String corpid = operationDTO.getCorpid();
        String parentAttr = "";
        Map<String, FieldAttrEntity> targetSubExplainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<String> targetAttrList = ExplainUtil.getAttrByPoint(operationsPojo.getAttr());
        if (ExplainUtil.isSubForm(targetField.getFieldType())) {
            String targetSubAttr = targetAttrList.get(1);
            List<? extends FieldAttrEntity> jsonArray = targetField.getSubForm().getItems();
            targetSubExplainMap = ExplainUtil.getExplainMapByList(jsonArray);
            targetField = targetSubExplainMap.get(targetSubAttr);
        }
        for (int i = 0; i < formulaArray.length; i++) {
            String formulaAttr = formulaArray[i];
            if (formulaAttr.contains("self.")) {
                // 本表单的字段操作
                String attr = formulaAttr.replaceAll("self.", "").replaceAll("[\\{\\}]", "");
                if (attr.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                    List<String> thisAttrList = ExplainUtil.getAttrByPoint(attr);
                    parentAttr = thisAttrList.get(0);
                    FieldAttrEntity thisField = thisExplainMap.get(parentAttr);
                    List<? extends FieldAttrEntity> jsonArray = thisField.getSubForm().getItems();
                    Map<String, FieldAttrEntity> thisSubExplainMap = ExplainUtil.getExplainMapByList(jsonArray);
                    explainMap.put(parentAttr, thisSubExplainMap);
                }
            }
        }
        // 拼装对象
        BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(corpid, operationDTO.getThisExplain(), operationDTO.getTargetExplain(), operationDTO.getTarget(), operationDTO.getFormId(),
                businessType, operationDTO.getSaasMark(), operationDTO.getOperationType(), operationDTO.getFormDataMap());
        JSONArray dataJsonArray = new JSONArray();
        if (Objects.nonNull(thisDataEntity.getSubFormData()) && Objects.nonNull(thisDataEntity.getSubFormData().get(parentAttr))) {
            dataJsonArray = thisDataEntity.getSubFormData().getJSONArray(parentAttr);
        }
        String targetAttr = targetField.getAttr();
        JSONArray resultJsonArray = new JSONArray();
        for (int i = 0; i < dataJsonArray.size(); i++) {
            String formula = operationsPojo.getFormulaInfo().getFormula();
            for (int j = 0; j < formulaArray.length; j++) {
                String formulaAttr = formulaArray[j];
                Object value = null;
                if (formulaAttr.contains("self.")) {
                    String attr = formulaAttr.replaceAll("self.", "").replaceAll("[\\{\\}]", "");
                    if (attr.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {
                        // 子表单数据
                        List<String> thisAttrList = ExplainUtil.getAttrByPoint(attr);
                        attr = thisAttrList.get(0);
                        String thisSubAttr = thisAttrList.get(1);
                        Map<String, FieldAttrEntity> thisSubFieldMap = explainMap.get(attr);
                        value = getData(thisSubAttr, thisSubFieldMap, thisDataEntity, dataJsonArray.getJSONObject(i), thisFormId, businessType, corpid, businessRuleInfoPojo);
                    } else {
                        value = getData(attr, thisExplainMap, thisDataEntity, thisData, thisFormId, businessType, corpid, businessRuleInfoPojo);
                    }
                } else if (RegexUtil.isStartWithNumber(formulaAttr)) {
                    // 目标表单
                    // TODO 缺少工单
                    Integer startNum = formulaAttr.indexOf(".")+1;
                    Integer length = formulaAttr.length();
                    String attr = formulaAttr.substring(startNum, length).replaceAll("[\\{\\}]", "");
                    if (attr.contains(FieldTypeEnum.SUB_FORM.getEsalias())) {

                        List<String> attrList = ExplainUtil.getAttrByPoint(attr);
                        attr = attrList.get(1);
                        value = getData(attr, targetSubExplainMap, new PaasFormDataEntity(), new JSONObject(), targetFormId, targetBusinessType, corpid, businessRuleInfoPojo);
                    } else {
                        value = getData(attr, targetExplainMap, new PaasFormDataEntity(), new JSONObject(), targetFormId, targetBusinessType, corpid, businessRuleInfoPojo);
                    }

                }  else if (formulaAttr.contains("user.")) {
                    value = formulaAttr.replace("user.", "").replaceAll("[\\{\\}]", "");
                } else if (formulaAttr.contains("dept.")) {
                    value = formulaAttr.replace("dept.", "").replaceAll("[\\{\\}]", "");
                }
                if (Objects.isNull(value)) {
                    formula = null;
                    break;
                }
                formula = formula.replace(formulaAttr, value.toString());
            }
            Object value = functionService.expressRun(formula, new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY));
            value = PaasStringUtil.replaceQuotes(value);
            value = getTargetDataByFieldType(targetExplainMap, value, operationsPojo, targetField, ruleTargetPojo, corpid, businessRuleInfoPojo);
            JSONObject result = new JSONObject();
            result.put(targetAttr, value);
            resultJsonArray.add(result);
        }
        return resultJsonArray;
    }


    /**
     * 业务规则简易版-加减计算
     * @param targetField
     * @param targetData
     * @param targetAttr
     * @param operationsPojo
     */
    public BigDecimal count(FieldAttrEntity targetField, JSONObject targetData, String targetAttr, OperationsPojo operationsPojo) throws XbbException {
        return FormDataUtil.count(targetField, targetData, targetAttr, operationsPojo.getValue(), operationsPojo.getSymbol());
    }


}
